#include "appa_dapter_controller.h"

AppAdapterController::AppAdapterController(QWidget *parent) : QMainWindow(parent), stackedWidget(new QStackedWidget(this))
{
    Pendant_Techn_Param_ptr = &Pendant_Techn_Param;
    initiateAlarmStruct();
    connect(this, &AppAdapterController::NewAlarmcreated, this, &AppAdapterController::createNewAlarm);
    setDefulatValue();


    thread.start();

    setPagesTopFrame(this);
    setPagesTopdisplayData();

    createMenu();
    createZeroReturnMode();
    createManualManipulation();
    createAutomaticMode();
    createUserSwitch();
    createSystemSetting();
    createExternalMemory();
    createCalTimer();
    createTeachMode();
    createProgramEditor();
    createTcpThread(ipAddress, tcp_port);
    createRS422Communication();
    createSpeedAddDec();

    setCentralWidget(stackedWidget);

    RestoreDoc2TechnParam(Pendant_Techn_Param_ptr, docPath);
    buildAutoProgram();

    QTimer *timer = new QTimer(this);
    timer->start(1000);
    connect(timer, &QTimer::timeout, [&](){
        this->detectAlarmState();
        systemSetting->displayUserLevel();
//        manualManipulation->saveButtonStates();
//        manualManipulation->parseIoState();
        manualManipulation->displayTechnParam(Pendant_Techn_Param_ptr);
        zeroReturnMode->displayTechnParam(Pendant_Techn_Param_ptr);
        programEditor->detectIfRowCntChange();
    });

    QTimer *timer_DocUpdate = new QTimer(this);
    timer_DocUpdate->start(5000);
    connect(timer_DocUpdate, &QTimer::timeout, [&](){
        RestoreTechnParam2Doc(Pendant_Techn_Param_ptr, docPath);
    });
}

void AppAdapterController::buildAutoProgram()
{
    XMLDocument XMLDoc_local;
    if(XMLDoc_local.LoadFile(programPath) == tinyxml2::XML_SUCCESS)
    {
        XMLElement* Root = XMLDoc_local.RootElement();
        if(Root)
        {
            XMLElement* programElem = Root->FirstChildElement("programName");
            if(programElem)
            {
                XMLElement* programNameElem = programElem->FirstChildElement("自动运转程序");
                if(programNameElem)
                    return;
            }
        }
    }
    else if(XMLDoc_local.LoadFile(programPath) != tinyxml2::XML_SUCCESS)
    {
        XMLDeclaration* declaration = XMLDoc_local.NewDeclaration();
        XMLDoc_local.InsertFirstChild(declaration);
        XMLElement* Root = XMLDoc_local.NewElement("root");
        XMLDoc_local.InsertEndChild(Root);
        XMLElement* programElem = XMLDoc_local.NewElement("programName");
        Root->InsertEndChild(programElem);
        XMLElement* programNameElem = XMLDoc_local.NewElement("自动运转程序");
        programElem->InsertEndChild(programNameElem);

        XMLElement* CellElem;

        CellElem = XMLDoc_local.NewElement(QString("Cell_0").toStdString().c_str());
        CellElem->SetAttribute("StepName", "直线移动");
        programNameElem->InsertEndChild(CellElem);
        setAxisMove(&XMLDoc_local, CellElem, "axis_mz", "0.0", "30");
        setAxisMove(&XMLDoc_local, CellElem, "axis_y", "12.8", "50");
        setAxisMove(&XMLDoc_local, CellElem, "axis_mx", "47.5", "50");

        CellElem = XMLDoc_local.NewElement(QString("Cell_1").toStdString().c_str());
        CellElem->SetAttribute("StepName", "回正");
        programNameElem->InsertEndChild(CellElem);

        CellElem = XMLDoc_local.NewElement(QString("Cell_2").toStdString().c_str());
        CellElem->SetAttribute("StepName", "直线移动");
        programNameElem->InsertEndChild(CellElem);
        setAxisMove(&XMLDoc_local, CellElem, "axis_mz", "132.6", "30");
        setAxisMove(&XMLDoc_local, CellElem, "axis_mx", "61.7", "50");

        CellElem = XMLDoc_local.NewElement(QString("Cell_3").toStdString().c_str());
        CellElem->SetAttribute("StepName", "直线移动");
        programNameElem->InsertEndChild(CellElem);
        setAxisMove(&XMLDoc_local, CellElem, "axis_mx", "41.7", "30");
        setAxisMove(&XMLDoc_local, CellElem, "axis_mz", "0.0", "30");

        CellElem = XMLDoc_local.NewElement(QString("Cell_4").toStdString().c_str());
        CellElem->SetAttribute("StepName", "直线移动");
        programNameElem->InsertEndChild(CellElem);
        setAxisMove(&XMLDoc_local, CellElem, "axis_y", "0.86", "50");
    }
    XMLDoc_local.SaveFile(programPath);
}

void AppAdapterController::setAxisMove(XMLDocument* doc, XMLElement* ele, const QString& axis_name,
                                       const QString& PosData, const QString& VelData) {
    if(PosData==QString("") || VelData==QString(""))
        return;
    XMLElement* axisElem = ele->FirstChildElement("axis");
    XMLElement* posElem;
    XMLElement* velElem;
    while(axisElem)
    {
        if(axisElem->Attribute("name") == axis_name)
        {
            posElem = axisElem->FirstChildElement("position");
            velElem = axisElem->FirstChildElement("velocity");
            break;
        }
        else
            axisElem = axisElem->NextSiblingElement("axis");
    }
    if(!axisElem)
    {
        XMLElement* new_axisElem = doc->NewElement("axis");
        new_axisElem->SetAttribute("name", axis_name.toStdString().c_str());
        ele->InsertEndChild(new_axisElem);
        posElem = doc->NewElement("position");
        new_axisElem->InsertEndChild(posElem);
        velElem = doc->NewElement("velocity");
        new_axisElem->InsertEndChild(velElem);
    }
    posElem->SetText(PosData.toStdString().c_str());
    velElem->SetText(VelData.toStdString().c_str());
}

void AppAdapterController::detectAlarmState() {
    for(int i=0; i<PendantAlarmNumForType.AlarmNum_OperateError; i++)
    {
        if(Pendant_Techn_Param_ptr->OperateErrorAlarm.isAlarmTrigged[i])
        {
            emit NewAlarmcreated("OperateErrorAlarm", i, Pendant_Techn_Param_ptr->OperateErrorAlarm.isAlarmTrigged[i]);
            return;
        }
    }
    for(int i=0; i<PendantAlarmNumForType.AlarmNum_Axis; i++)
    {
        if(Pendant_Techn_Param_ptr->AxisAlarm.isAlarmTrigged[i])
        {
            emit NewAlarmcreated("AxisAlarm", i, Pendant_Techn_Param_ptr->AxisAlarm.isAlarmTrigged[i]);
            return;
        }
    }
}

void AppAdapterController::createNewAlarm(QString alarmName, int alarmNum, bool ifDisplayNewAlarm) {

    QDialog* newAlarm = new QDialog();
    newAlarm_stack.push(newAlarm);
    newAlarm->setStyleSheet("background-color: rgb(173, 216, 230); color: black; font-size: 12pt;");
    newAlarm->setFixedSize(QSize(400, 300));
    QLabel* AlarmTitle;
    AlarmTitle = new QLabel("警告");
    AlarmTitle->setStyleSheet({"text-align: center; font-size: 25px; background-color: rgb(229, 232, 237)"});
    AlarmTitle->setParent(newAlarm);
    AlarmTitle->move(10, 10);
    if(ifDisplayNewAlarm)
    {
        QLabel* Alarmlabel;
        if(alarmName == "OperateErrorAlarm")
        {
           Alarmlabel = new QLabel(Pendant_Techn_Param_ptr->OperateErrorAlarm.AlarmContent[alarmNum]);
           Pendant_Techn_Param_ptr->OperateErrorAlarm.isAlarmTrigged[alarmNum] = 0;
        }
        if(alarmName == "AxisAlarm")
        {
           Alarmlabel = new QLabel(Pendant_Techn_Param_ptr->AxisAlarm.AlarmContent[alarmNum]);
           Pendant_Techn_Param_ptr->AxisAlarm.isAlarmTrigged[alarmNum] = 0;
        }
        Alarmlabel->setFixedSize(300, 200);
        Alarmlabel->setWordWrap(true);
        Alarmlabel->setAlignment(Qt::AlignCenter);
        Alarmlabel->setParent(newAlarm);
        int labelX = (newAlarm->width() - Alarmlabel->width()) / 2;
        int labelY = (newAlarm->height() - Alarmlabel->height()) / 2;
        Alarmlabel->move(labelX, labelY);
        Alarmlabel->setWordWrap(true);
        QWidget* widget = stackedWidget->currentWidget();
        newAlarm->setParent(widget);
        newAlarm->move(150, 80);
        newAlarm->show();
        if(stackedWidget->currentWidget()->findChild<QPushButton*>("ButtonAlarm"))
        {
            connect(stackedWidget->currentWidget()->findChild<QPushButton*>("ButtonAlarm"), &QPushButton::clicked, this, &AppAdapterController::closeAlarmWidget);
        }
   }
}

void AppAdapterController::closeAlarmWidget() {
    disconnect(stackedWidget->currentWidget()->findChild<QPushButton*>("ButtonAlarm"), &QPushButton::clicked, this, &AppAdapterController::closeAlarmWidget);
    if(!newAlarm_stack.isEmpty())
    {
       newAlarm_stack.pop()->hide();
    }
    connect(stackedWidget->currentWidget()->findChild<QPushButton*>("ButtonAlarm"), &QPushButton::clicked, this, &AppAdapterController::closeAlarmWidget);
}

void AppAdapterController::isFileExist() {
    create_xml(sendPath);
    parse_xml(sendPath);

    create_xml(receivePath);
    parse_xml(receivePath);
}

void AppAdapterController::createMenu()
{
    menu = new Menu(this);
    stackedWidget->addWidget(menu);
    connect(menu, &Menu::go2ReturnZero, this, &AppAdapterController::go2ReturnZero);
    connect(menu, &Menu::go2Manual, this, &AppAdapterController::go2Manual);
    connect(menu, &Menu::go2Automatic, this, &AppAdapterController::go2Automatic);
    connect(menu, &Menu::go2UserSwitch, this, &AppAdapterController::go2UserSwitch);
    connect(menu, &Menu::go2SystemSetting, this, &AppAdapterController::go2SystemSetting);
    connect(menu, &Menu::go2ExternalMemory, this, &AppAdapterController::go2ExternalMemory);
    connect(menu, &Menu::go2CalTimer, this, &AppAdapterController::go2CalTimer);
    connect(menu, &Menu::go2TeachMode, this, &AppAdapterController::go2TeachMode);
    connect(menu, &Menu::go2ProgramEditor, this, &AppAdapterController::go2ProgramEditor);
    connect(menu, &Menu::IfTcpCommunicationGoOn, this, &AppAdapterController::TcpCommunicationFlipped);
    connect(menu, &Menu::AbortTcpConnect, this, &AppAdapterController::abortTcpConnect);
    connect(menu, &Menu::go2RS422Communication, this, &AppAdapterController::go2RS422Communication);
    connect(menu, &Menu::go2SpeedAddDec, this, &AppAdapterController::go2SpeedAddDec);
}

void AppAdapterController::createZeroReturnMode()
{
    zeroReturnMode = new ZeroReturnMode(this);
    stackedWidget->addWidget(zeroReturnMode);
    connectModeSignals(zeroReturnMode);
}

void AppAdapterController::createManualManipulation()
{
    manualManipulation = new ManualManipulation(this);
    stackedWidget->addWidget(manualManipulation);
    connectModeSignals(manualManipulation);
}

void AppAdapterController::createAutomaticMode()
{
    automaticMode = new AutomaticMode(this);
    stackedWidget->addWidget(automaticMode);
    connectModeSignals(automaticMode);
}

void AppAdapterController::createProgramEditor()
{
    programEditor = new ProgramEditor(this);
    stackedWidget->addWidget(programEditor);
    connect(programEditor, &ProgramEditor::returnMenu, this, &AppAdapterController::returnMenu);
    connect(programEditor, &ProgramEditor::sendProgramContent, this, static_cast<void (AppAdapterController::*)(const QString &ProgramName)>(&AppAdapterController::sendParamValue_TCP));
}

void AppAdapterController::createTeachMode()
{
    teachMode = new TeachMode(this);
    stackedWidget->addWidget(teachMode);
    connect(teachMode, &TeachMode::returnMenu, this, &AppAdapterController::returnMenu);
    connect(teachMode, &TeachMode::go2ProgramEditor_,this, &AppAdapterController::go2ProgramEditor);

}

void AppAdapterController::createUserSwitch()
{
    userSwitch = new UserSwitch(this);
    stackedWidget->addWidget(userSwitch);
    connect(userSwitch, &UserSwitch::returnMenu, this, &AppAdapterController::returnMenu);
}

void AppAdapterController::createSystemSetting()
{
    systemSetting = new SystemSetting(this);
    stackedWidget->addWidget(systemSetting);
    connect(systemSetting, &SystemSetting::returnMenu, this, &AppAdapterController::returnMenu);
}

void AppAdapterController::createExternalMemory()
{
    externalMemory = new ExternalMemory(this);
    stackedWidget->addWidget(externalMemory);
    connect(externalMemory, &ExternalMemory::returnMenu, this, &AppAdapterController::returnMenu);
}

void AppAdapterController::createCalTimer()
{
    calTimer = new CalTimer(this);
    stackedWidget->addWidget(calTimer);
    connect(calTimer, &CalTimer::returnMenu, this, &AppAdapterController::returnMenu);
}

void AppAdapterController::createTcpThread(QHostAddress ip, QString port)
{
    tcp_communication_thread = new tcp_thread(ip, port);
    tcp_communication_thread->start();
    connect(tcp_communication_thread, &tcp_thread::AbortTcpConnect, this, &AppAdapterController::stopTcpConnect);
}

void AppAdapterController::createRS422Communication()
{
    rs422SerialPort = new rs422_serial_port();
    stackedWidget->addWidget(rs422SerialPort);
    connect(rs422SerialPort, &rs422_serial_port::returnMenu, this, &AppAdapterController::returnMenu);
}

void AppAdapterController::createSpeedAddDec()
{
    speedAddDec = new speed_add_dec(this);
    stackedWidget->addWidget(speedAddDec);
    connect(speedAddDec, &speed_add_dec::returnMenu, this, &AppAdapterController::returnMenu);
}

AppAdapterController::~AppAdapterController()
{
}

void AppAdapterController::connectModeSignals(QObject* mode)
{
    if (mode->objectName() == "ZeroReturnMode") {
        connect(dynamic_cast<ZeroReturnMode*>(mode), &ZeroReturnMode::returnMenu, this, &AppAdapterController::returnMenu);
        connect(dynamic_cast<ZeroReturnMode*>(mode), &ZeroReturnMode::returnTeachMode, this, &AppAdapterController::go2TeachMode);
        connect(dynamic_cast<ZeroReturnMode*>(mode), &ZeroReturnMode::returnCalTimer, this, &AppAdapterController::go2CalTimer);
        connect(dynamic_cast<ZeroReturnMode*>(mode), &ZeroReturnMode::returnManual, this, &AppAdapterController::go2Manual);
        connect(dynamic_cast<ZeroReturnMode*>(mode), &ZeroReturnMode::returnAutomatic, this, &AppAdapterController::go2Automatic);
        connect(dynamic_cast<ZeroReturnMode*>(mode), &ZeroReturnMode::addSpeedValue, this, &AppAdapterController::addSpeedValue);
        connect(dynamic_cast<ZeroReturnMode*>(mode), &ZeroReturnMode::decSpeedValue, this, &AppAdapterController::decSpeedValue);
    }
    else if (mode->objectName() == "ManualManipulation") {
        connect(dynamic_cast<ManualManipulation*>(mode), &ManualManipulation::returnMenu, this, &AppAdapterController::returnMenu);
        connect(dynamic_cast<ManualManipulation*>(mode), &ManualManipulation::returnTeachMode, this, &AppAdapterController::go2TeachMode);
        connect(dynamic_cast<ManualManipulation*>(mode), &ManualManipulation::returnCalTimer, this, &AppAdapterController::go2CalTimer);
        connect(dynamic_cast<ManualManipulation*>(mode), &ManualManipulation::returnZero, this, &AppAdapterController::go2ReturnZero);
        connect(dynamic_cast<ManualManipulation*>(mode), &ManualManipulation::returnAutomatic, this, &AppAdapterController::go2Automatic);
        connect(dynamic_cast<ManualManipulation*>(mode), &ManualManipulation::addSpeedValue, this, &AppAdapterController::addSpeedValue);
        connect(dynamic_cast<ManualManipulation*>(mode), &ManualManipulation::decSpeedValue, this, &AppAdapterController::decSpeedValue);
        connect(dynamic_cast<ManualManipulation*>(mode), &ManualManipulation::sendParamValue_TCP_, this, static_cast<void (AppAdapterController::*)(const QString &MsgSentType, const QString &ParamName, const QString &ParamAttribute)>(&AppAdapterController::sendParamValue_TCP));
    }
    else if (mode->objectName() == "AutomaticMode") {
        connect(dynamic_cast<AutomaticMode*>(mode), &AutomaticMode::returnMenu, this, &AppAdapterController::returnMenu);
        connect(dynamic_cast<AutomaticMode*>(mode), &AutomaticMode::addSpeedValue, this, &AppAdapterController::addSpeedValue);
        connect(dynamic_cast<AutomaticMode*>(mode), &AutomaticMode::decSpeedValue, this, &AppAdapterController::decSpeedValue);
    }
}

void AppAdapterController::go2CalTimer()
{
    stackedWidget->setCurrentWidget(calTimer);
    pendantInterfaceData.pageName = "计时器";
    calTimer->re_setupUiAppearance();
}

void AppAdapterController::go2TeachMode()
{
    stackedWidget->setCurrentWidget(teachMode);
    pendantInterfaceData.pageName = "教导";
    teachMode->changeProgramEditAuthority();
}

void AppAdapterController::go2ProgramEditor(const QString &buttonName)
{
    stackedWidget->setCurrentWidget(programEditor);
    pendantInterfaceData.pageName = "程序编辑";
    programEditor->setProgramName(buttonName);
    programEditor->changeProgramEditAuthority();
    programEditor->hideInsertRowButtonDisplay();
    
}

void AppAdapterController::go2ExternalMemory()
{
    stackedWidget->setCurrentWidget(externalMemory);
    pendantInterfaceData.pageName = "外部存储器";
}

void AppAdapterController::go2ReturnZero()
{
    stackedWidget->setCurrentWidget(zeroReturnMode);
    zeroReturnMode->updateMantuableData();
    pendantInterfaceData.pageName = "原点";
    pendantInterfaceData.actionMode = "原点复归";
}

void AppAdapterController::go2UserSwitch()
{
    stackedWidget->setCurrentWidget(userSwitch);
    pendantInterfaceData.pageName = "用户切换";
}

void AppAdapterController::go2Manual()
{
    stackedWidget->setCurrentWidget(manualManipulation);
    manualManipulation->updateMantuableData();
    pendantInterfaceData.pageName = "手动";
    pendantInterfaceData.actionMode = "手动操作";
}

void AppAdapterController::go2Automatic()
{
    stackedWidget->setCurrentWidget(automaticMode);
    automaticMode->updateMantuableData();
    pendantInterfaceData.pageName = "自动";
    pendantInterfaceData.actionMode = "自动运转";
}

void AppAdapterController::go2SystemSetting()
{
    stackedWidget->setCurrentWidget(systemSetting);
    pendantInterfaceData.pageName = "系统设置";
}

void AppAdapterController::go2SpeedAddDec()
{
    stackedWidget->setCurrentWidget(speedAddDec);
    pendantInterfaceData.pageName = "加减速设定";
}

void AppAdapterController::returnMenu()
{
    stackedWidget->setCurrentWidget(menu);
    pendantInterfaceData.pageName = "菜单";
}

void AppAdapterController::addSpeedValue()
{
    if (pendantInterfaceData.speedMutableLabel == "中速")
        pendantInterfaceData.speedMutableLabel = "高速";
    if (pendantInterfaceData.speedMutableLabel == "低速")
        pendantInterfaceData.speedMutableLabel = "中速";
}

void AppAdapterController::decSpeedValue()
{
    if (pendantInterfaceData.speedMutableLabel == "中速")
        pendantInterfaceData.speedMutableLabel = "低速";
    if (pendantInterfaceData.speedMutableLabel == "高速")
        pendantInterfaceData.speedMutableLabel = "中速";
}

void AppAdapterController::sendParamValue_TCP(const QString &MsgSentType, const QString &ParamName, const QString &ParamAttribute)
{
    if(tcp_communication_thread->TCPthread_connect_flag && tcp_communication_thread->TCPthread_start_flag && tcp_communication_thread->TCPthread_send_flag)
    {
        //qDebug() << "即将发送出去的数据是" << ParamName << ParamAttribute;
        // Test，示教器的 待Tcp输出的操作 可以以约定格式存入xml中，ok！
        // TCP_msg_xml("/home/byh/QtProjects/gantry-robot-master/TcpSendTest.xml");

        XMLDocument doc_temp;
        XMLElement* elementptr = doc_temp.NewElement(ParamName.toStdString().c_str());
        doc_temp.InsertEndChild(elementptr);

        if(MsgSentType == "IoOutput")
        {
            elementptr->SetAttribute("IoState", ParamAttribute.toStdString().c_str());
            const XMLAttribute* ele_attribute_ptr = elementptr->FirstAttribute();
            //qDebug() << "即将发送出去的元素1 2 3分别是" << elementptr->Name() << ele_attribute_ptr->Name() << ele_attribute_ptr->Value();
            setIoParam(elementptr, ele_attribute_ptr, Pendant_Techn_Param_ptr);
        }

        XMLPrinter printer;
        doc_temp.Print(&printer);
        std::string xmlString = printer.CStr();
        QString qstr = QString::fromStdString(xmlString);
        //qDebug() << "即将发送出去的元素1 2 3放入xml格式是" << qstr;
        TCP_SendMsg_queue.enqueue(qstr);
    }
}

void AppAdapterController::sendParamValue_TCP(const QString &ProgramName)
{
    if(tcp_communication_thread->TCPthread_connect_flag && tcp_communication_thread->TCPthread_start_flag && tcp_communication_thread->TCPthread_send_flag)
    {
        XMLDocument doc_temp;
        XMLElement* elementptr = doc_temp.NewElement("program");
        doc_temp.InsertEndChild(elementptr);

        QFile file(programPath);
        XMLDocument XMLDoc_local;
        if (file.exists() && XMLDoc_local.LoadFile(programPath) == tinyxml2::XML_SUCCESS)
        {
            if(XMLDoc_local.RootElement())
            {
                XMLElement* programElem = XMLDoc_local.RootElement()->FirstChildElement("programName");
                if(programElem)
                {
                    XMLElement* programNameElem = programElem->FirstChildElement(ProgramName.toStdString().c_str());
                    if(programNameElem)
                    {
                        XMLElement* programNameElem_TcpXml = doc_temp.NewElement("programName");
                        programNameElem_TcpXml->SetAttribute("v", ProgramName.toStdString().c_str());
                        elementptr->InsertEndChild(programNameElem_TcpXml);
                        int a = 0;
                        while(programNameElem->FirstChildElement((QString("Cell_%1").arg(a)).toStdString().c_str()))
                        {
                            XMLElement* ele = programNameElem->FirstChildElement((QString("Cell_%1").arg(a)).toStdString().c_str());
                            a++;
                            parseFromProgramXml2TcpXml(ele, &doc_temp, elementptr);
                        }
                    }
                }
            }
        }

        XMLPrinter printer;
        doc_temp.Print(&printer);
        std::string xmlString = printer.CStr();
        QString qstr = QString::fromStdString(xmlString);
        //qDebug() << "即将发送出去的元素1 2 3放入xml格式是" << qstr;
        TCP_SendMsg_queue.enqueue(qstr);
    }
}

void AppAdapterController::parseFromProgramXml2TcpXml(XMLElement* ele_ProgramXml, XMLDocument* doc_TcpXml, XMLElement* ele_TcpXml)
{
    QString ProgramXml_CellName = ele_ProgramXml->Attribute("StepName");
    if(ProgramXml_CellName == "直线移动")
    {
        XMLElement* TcpXml_Step = doc_TcpXml->NewElement("move");
        ele_TcpXml->InsertEndChild(TcpXml_Step);

        XMLElement* ProgramXml_Axis = ele_ProgramXml->FirstChildElement("axis");
        while(ProgramXml_Axis)
        {
            XMLElement* TcpXml_NewAxis = doc_TcpXml->NewElement("axis");
            TcpXml_NewAxis->SetAttribute("name", ProgramXml_Axis->Attribute("name"));
            TcpXml_Step->InsertEndChild(TcpXml_NewAxis);
            XMLElement* posElem = doc_TcpXml->NewElement("position");
            posElem->SetText(ProgramXml_Axis->FirstChildElement("position")->GetText());
            TcpXml_NewAxis->InsertEndChild(posElem);
            XMLElement* velElem = doc_TcpXml->NewElement("velocity");
            velElem->SetText(ProgramXml_Axis->FirstChildElement("velocity")->GetText());
            TcpXml_NewAxis->InsertEndChild(velElem);

            ProgramXml_Axis = ProgramXml_Axis->NextSiblingElement("axis");
        }
    }
    else if(ProgramXml_CellName == "侧姿")
    {

    }
}

void AppAdapterController::TCP_msg_xml(const char* xmlPath)
{
    std::ifstream file(xmlPath);
    bool fileExists = file.good();
    file.close();

    if (!fileExists) {
        XMLDocument doc;
        XMLDeclaration* declaration = doc.NewDeclaration();
        doc.InsertFirstChild(declaration);
        XMLElement* rootElement = doc.NewElement("root");
        doc.InsertEndChild(rootElement);

        QString q1 = TCP_SendMsg_queue.dequeue();
        QString q2 = TCP_SendMsg_queue.dequeue();

        char * c1 = q1.toUtf8().data();
        char * c2 = q2.toUtf8().data();

        XMLElement* program = doc.NewElement("IoInput");
        rootElement->InsertEndChild(program);
        XMLElement* programElement = doc.NewElement(c1);

        programElement->SetAttribute("IoState", c2);
        program->InsertEndChild(programElement);

        if (doc.SaveFile(xmlPath) == XML_SUCCESS) {
            std::cout << "XML file created successfully." << std::endl;
        } else {
            std::cout << "Error creating XML file." << std::endl;
        }
    }
}

void AppAdapterController::TcpCommunicationFlipped(bool ifTcpGoOn)
{
    if(tcp_communication_thread->TCPthread_connect_flag)
    {
        if(ifTcpGoOn)
        {
            tcp_communication_thread->mutex_GoOn();
            tcp_communication_thread->TCPthread_send_flag = true;
            tcp_communication_thread->TCPthread_receive_flag = true;
        }
        else
        {
            tcp_communication_thread->mutex_Stop();
            tcp_communication_thread->TCPthread_send_flag = false;
            tcp_communication_thread->TCPthread_receive_flag = false;
            data_buffer_QS.clear();
        }
    }
}

void AppAdapterController::abortTcpConnect()
{
    data_buffer_QS.clear();
    tcp_communication_thread->mutex_GoOn();

    // 停止
    tcp_communication_thread->TCPthread_start_flag = false;
    tcp_communication_thread->TCPthread_send_flag = false;
    tcp_communication_thread->TCPthread_receive_flag = false;

    tcp_communication_thread->quit();
    tcp_communication_thread->wait();
    if(tcp_communication_thread->TCPthread_connect_flag)
    {
        tcp_communication_thread->tcp_socket->abort();
        tcp_communication_thread->tcp_server->close();
        tcp_communication_thread->TCPthread_connect_flag = false;
    }
    qDebug() << "TCP线程被销毁";
}

void AppAdapterController::stopTcpConnect()
{
    data_buffer_QS.clear();
    if(tcp_communication_thread->TCPthread_connect_flag)
    {
        tcp_communication_thread->mutex_Stop();
        tcp_communication_thread->TCPthread_connect_flag = false;
        tcp_communication_thread->TCPthread_start_flag = false;
        tcp_communication_thread->TCPthread_send_flag = false;
        tcp_communication_thread->TCPthread_receive_flag = false;
    }
}

void AppAdapterController::go2RS422Communication()
{
    stackedWidget->setCurrentWidget(rs422SerialPort);
    pendantInterfaceData.pageName = "RS422串口";
}
